-- 运营活动: 超值限购


--[[
{
    cmd_id = 1, -- 命令id，用于批量停止、删除活动  
    act_id = 99, -- 活动id (99 嗨购一车)
    act_name = '嗨购一车', -- 活动名称
    act_desc = '活动期间消费元宝即获得等量的消费积分！', -- 活动描述
    beg_time = 1493262000,  -- 活动开始时间(unix timestamp)
    end_time = 1693267400,  -- 活动结束时间(unix timestamp)
    config = { -- 配置数据
        dailyExchange = 1, --每次兑换标志，如果是1则是每日兑换，如果是0 则是活动期间兑换
        limitBuyNum = 10, --购物车提交次数
        limitItemNum = 5, --购物车可以放物品个数
        discountList = 
        {
            {
                num = 1,   --物品数量 
                discount = 0.1,  --打折多少，（价格等于总价格 - math.floor(总价*折扣)）
            },
            {
                num = 2,   --物品数量 
                discount = 0.2,  --打折多少，（价格等于总价格 - math.floor(总价*折扣)）
            },
        },
        ItemList = 
        {
            { 
                itemIdx = 1, type = 0, id = 581, count = 1, bind = 1,  costNum = 500,
            },
            { 
                itemIdx = 2, type = 0, id = 582, count = 1, bind = 1,  costNum = 500,
            },
            { 
                itemIdx = 3, type = 0, id = 581, count = 1, bind = 1,  costNum = 500,
            },
            { 
                itemIdx = 4, type = 0, id = 582, count = 1, bind = 1,  costNum = 500,
            },
            { 
                itemIdx = 5, type = 0, id = 581, count = 1, bind = 1,  costNum = 500,
            },
            { 
                itemIdx = 6, type = 0, id = 582, count = 1, bind = 1,  costNum = 500,
            },
            { 
                itemIdx = 7, type = 0, id = 581, count = 1, bind = 1,  costNum = 500,
            },
            { 
                itemIdx = 8, type = 0, id = 582, count = 1, bind = 1,  costNum = 500,
            },
            { 
                itemIdx = 9, type = 0, id = 581, count = 1, bind = 1,  costNum = 500,
            },
            { 
                itemIdx = 10, type = 0, id = 582, count = 1, bind = 1,  costNum = 500,
            },
            { 
                itemIdx = 11, type = 0, id = 581, count = 1, bind = 1,  costNum = 500,
            },
            { 
                itemIdx = 12, type = 0, id = 582, count = 1, bind = 1,  costNum = 500,
            },
        },
    },
}
]]

-- 检查配置是否正确，正确则返回 0，否则返回错误码
function oper_act_99_check_cfg(cfg)
    if cfg == nil then return 20 end
    
    local config = cfg.config
    if config == nil then return 21 end
    
    if config.ItemList == nil then return 23 end
    if type(config.ItemList) ~= "table" then return 24 end
    if not oper_act_check_one_award_cfg(config.ItemList) then
        return 22
    end 

    return 0
end

-- 安装活动，成功则返回 0，否则返回错误码
function oper_act_99_setup(cfg) 
    return 0
end

-- 卸载活动
function oper_act_99_unsetup(cfg)   
end

-- 活动开始
function oper_act_99_start(cfg)
    local ssVar = System.getStaticVar()
    ssVar.oper_act_99_start = 1
    ssVar.oper_act_99_cmd = cfg.cmd_id
    ssVar.oper_act_99_act = cfg.act_id

    local data = gRankMgr_GetValueByIndx(0, RANK_DEFINE_OPERATION_99, 1)

    if data then
        local myData = BaseFuc_unserialize(data)
        if myData and myData.cmd_id and myData.cmd_id == cfg.cmd_id and myData.act_id and myData.act_id == cfg.act_id and
            myData.time and cfg.beg_time <= myData.time and  cfg.end_time > myData.time then
            return
        end
    end

    gRankMgr_Clear(RANK_DEFINE_OPERATION_99)
end

-- 活动结束
function oper_act_99_end(cfg)
    local ssVar = System.getStaticVar()
    ssVar.oper_act_99_start = nil
    ssVar.oper_act_99_cmd = nil
    ssVar.oper_act_99_act = nil
end

-- 打包数据
function oper_act_99_packet_data(sysarg, cfg)

    local ssVar = System.getStaticVar()
    if not ssVar.oper_act_99_start then
        return
    end
    if not cfg then
        return
    end

    local config = cfg.config
    if not config then
        return
    end

    
    local actorid = Actor.getActorId(sysarg)
    local data = gRankMgr_GetValueById(actorid, RANK_DEFINE_OPERATION_99, 1)
    local myData = BaseFuc_unserialize(data)

    if not myData or myData == "" or myData == 0 then
        myData = {}
    end

    local time = System.getSystemTime()
    if config.dailyExchange and config.dailyExchange == 1 and myData.mySelfTime and not System.isUnixTimeSameDay(myData.mySelfTime, time) then
        myData.myBuyLimit = 0
    end

    if not myData.myBuyLimit then
        myData.myBuyLimit = 0
    end

    if not myData.myItemList then
        myData.myItemList = {}
    end

    local pack = oper_act_alloc_init_data_packet(sysarg, cfg.cmd_id, cfg.act_id)
    if (pack == nil) then
        return
    end

    DataPack.writeByte(pack, myData.myBuyLimit)

    local len = #myData.myItemList
    local count = 0
    local pos = DataPack.getDataPackPos(pack)
    DataPack.writeByte(pack, 0)
    if len > 1 then
        for idx = 1, len do
            local item = config.ItemList[myData.myItemList[idx]]
            if item then
                DataPack.writeShort(pack, item.itemIdx)
                count = count + 1
                if count >= config.limitItemNum then
                    break
                end
            end
        end
        DataPack.writeByteByPtr(pack, pos, count)
    end
    DataPack.flush(pack)

    --DataPack.writeByte(netPack, 1)        -- 活动特有参数
end


-- 操作，返回操作结果，0为成功
function oper_act_99_do(sysarg, cfg, clientPkt)
    if cfg == nil then return end
    
    if cfg.state == nil or cfg.state ~= 1 then -- 不在活动中
        Actor.sendTipmsg(sysarg,Lang.ScriptTips.Operation001, ttFlyTip)
        return
    end
    
    local config = cfg.config
    if config == nil then -- 参数错误
        print("error, oper_act_99_do cfg.config confg error")
        return
    end
    local actorid = Actor.getActorId(sysarg)
    local data = gRankMgr_GetValueById(actorid, RANK_DEFINE_OPERATION_99, 1)

    local myData = BaseFuc_unserialize(data)
    

    if not myData or myData == "" or myData == 0 then
        myData = {}
    end

    local time = System.getSystemTime()
    if config.dailyExchange and config.dailyExchange == 1 and myData.mySelfTime and not System.isUnixTimeSameDay(myData.mySelfTime, time) then
        myData.myBuyLimit = 0
    end

    if not myData.myBuyLimit then
        myData.myBuyLimit = 0
    end

    if not myData.myItemList then
        myData.myItemList = {}
    end

    local opType = DataPack.readByte( clientPkt )
    if opType == 1 then
        local nIndex = DataPack.readShort( clientPkt )
        local item = config.ItemList[nIndex]
        if not item then
            Actor.sendTipmsg(sysarg,Lang.ScriptTips.Operation015, ttFlyTip)
            return
        end
        local len = #myData.myItemList
        if len >= config.limitItemNum then
            Actor.sendTipmsg(sysarg,Lang.ScriptTips.Operation248, ttFlyTip)
            return
        end
        --[[
        if len > 0 then
            for idx = 1, len do
                if nIndex == myData.myItemList[idx] then
                    Actor.sendTipmsg(sysarg,Lang.ScriptTips.Operation247, ttFlyTip)
                    return
                end
            end
        end
        ]]
        table.insert(myData.myItemList, nIndex)

        if not myData.cmd_id then
            myData.cmd_id = cfg.cmd_id
            myData.act_id = cfg.act_id
            myData.time = time
        end

        myData.mySelfTime = time

        local newData = BaseFuc_serialize(myData)

        gRankMgr_SetRankEx(actorid, RANK_DEFINE_OPERATION_99, 1, newData)
        local netPack = oper_act_alloc_do_result_packet(sysarg, cfg.cmd_id, cfg.act_id, result)
        if not netPack then
            return
        end
        DataPack.writeByte(netPack, opType)
        DataPack.writeShort(netPack, nIndex)
        DataPack.flush(netPack)
    elseif opType == 2 then
        local nIndex = DataPack.readShort( clientPkt )
        local item = config.ItemList[nIndex]
        if not item then
            Actor.sendTipmsg(sysarg,Lang.ScriptTips.Operation015, ttFlyTip)
            return
        end
        local ii
        local len = #myData.myItemList
        if len > 0 then
            for idx = 1, len do
                if nIndex == myData.myItemList[idx] then
                    ii = idx
                    break
                end
            end
        end
        if not ii then
            Actor.sendTipmsg(sysarg,Lang.ScriptTips.Operation249, ttFlyTip)
            return
        end
        if ii == len then
            myData.myItemList[ii] = nil
        else
            myData.myItemList[ii] = myData.myItemList[len]
            myData.myItemList[len] = nil
        end
        if not myData.cmd_id then
            myData.cmd_id = cfg.cmd_id
            myData.act_id = cfg.act_id
            myData.time = time
        end

        myData.mySelfTime = time

        local newData = BaseFuc_serialize(myData)

        gRankMgr_SetRankEx(actorid, RANK_DEFINE_OPERATION_99, 1, newData)
        local netPack = oper_act_alloc_do_result_packet(sysarg, cfg.cmd_id, cfg.act_id, result)
        if not netPack then
            return
        end
        DataPack.writeByte(netPack, opType)
        DataPack.writeShort(netPack, nIndex)
        DataPack.flush(netPack)
    elseif opType == 3 then
        local len = #myData.myItemList
        if len <= 0 then
            Actor.sendTipmsg(sysarg,Lang.ScriptTips.Operation250, ttFlyTip)
            return
        end
        if myData.myBuyLimit >= config.limitBuyNum then
            Actor.sendTipmsg(sysarg,Lang.ScriptTips.Operation251, ttFlyTip)
            return
        end 
        local myRewards = {}
        local myCostNum = 0
        for idx = 1, len do
            local item = config.ItemList[myData.myItemList[idx]]
            if item then
                table.insert(myRewards, item)
                myCostNum = myCostNum + item.costNum
            end
        end

        if myCostNum <= 0 then
            Actor.sendTipmsg(sysarg,Lang.ScriptTips.Operation252, ttFlyTip)
            return
        end

        if IsBagGridEnough(sysarg, myRewards) then
            local disConfig
            for ii = 1, #config.discountList do
                local discountConfig = config.discountList[ii]
                if len >= discountConfig.num  then
                    disConfig = discountConfig
                    break
                end
            end

            if disConfig then
                myCostNum = math.ceil(myCostNum*disConfig.discount)
            end

            if myCostNum <= 0 then
                Actor.sendTipmsg(sysarg,Lang.ScriptTips.Operation252, ttFlyTip)
                return
            end
       
            if Actor.getMoneyCount(sysarg, mtYuanbao) < myCostNum then
                Actor.sendItemLack( sysarg, qatYuanbao, 0, myCostNum )
                return
            end

            if not Actor.delMoney( sysarg,mtYuanbao,myCostNum,LogIds.OperationLogId099,Lang.LogTips.Operation099) then
                return
            end

            myData.myBuyLimit = myData.myBuyLimit + 1
            myData.myItemList = {}
            GiveCommonAward(sysarg, myRewards, LogIds.OperationLogId099, Lang.LogTips.Operation099)

            if not myData.cmd_id then
                myData.cmd_id = cfg.cmd_id
                myData.act_id = cfg.act_id
                myData.time = time
            end

            myData.mySelfTime = time

            local newData = BaseFuc_serialize(myData)

            gRankMgr_SetRankEx(actorid, RANK_DEFINE_OPERATION_99, 1, newData)


            oper_act_99_packet_data(sysarg, cfg)
        else
            Actor.sendTipmsg(sysarg,Lang.ScriptTips.COM0015, ttFlyTip)
            return
        end

    else
        return
    end
end


--[[
-- 跨天
function oper_act_99_new_day_arrive(act_id)  
    
end
]]




